﻿using System;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using 纸片人.AttributeUsageFloder;

namespace 纸片人.Shaders
{
    public enum ShaderType
    {
        // 无
        None,
        [ShaderInfo("区域采样", "ms-appx:///Shaders/AreaSampling.txt", "用于制作显示选区内容效果")]
        AreaSampling,
        [ShaderInfo("非黑即白效果", "ms-appx:///Shaders/BlackOrWhiteShader.txt", "根据阈值显示像素 黑色/白色")]
        BlackOrWhite,
        [ShaderInfo("亮度转透明度", "ms-appx:///Shaders/BrightnessToTransparencyShader.txt", "先将像素转换成灰度，根据灰度和阈值进行比较，再觉得是否显示")]
        BrightnessToTransparency,
        [ShaderInfo("清除透明度", "ms-appx:///Shaders/ClearTransparencyEffectShader.txt", "将像素的透明度设置为不透明")]
        ClearTransparency,
        [ShaderInfo("颜色过渡", "ms-appx:///Shaders/ColorFade.txt", "将两个颜色根据阈值进行插值")]
        ColorFade,
        [ShaderInfo("颜色替换", "ms-appx:///Shaders/ColorReplacementShader.txt", "将指定的颜色替换成目标颜色")]
        ColorReplacement,
        [ShaderInfo("溶解效果", "ms-appx:///Shaders/DissolveShader.txt", "图片根据指定的阈值进行消失")]
        Dissolve,
        [ShaderInfo("扭曲效果", "ms-appx:///Shaders/DistortionShader.txt", "图片根据指定的角度和位置进行扭曲")]
        Distortion,
        [ShaderInfo("自由变换", "ms-appx:///Shaders/FreeTransform.txt")]
        FreeTransform,
        [ShaderInfo("渐变映射", "ms-appx:///Shaders/GradientMapping.txt", "先将像素转换成灰度，再从映射表中获取颜色")]
        GradientMapping,
        [ShaderInfo("高亮效果", "ms-appx:///Shaders/HighlightRevealShader.txt", "指定位置，指定半径，的区域进行高亮")]
        HighlightReveal,
        [ShaderInfo("突出显示", "ms-appx:///Shaders/LalphaMask.txt", "给定三张纹理，根据第一张纹理的像素透明值显示 第二或者第三张纹理的像素")]
        LalphaMask,
        [ShaderInfo("碰撞或挤压效果", "ms-appx:///Shaders/SwellOrExtrusionShader.txt", "指定位置，半径，阈值-1~1，来进行图像膨胀或者压缩")]
        SwellOrExtrusion,
        [ShaderInfo("波纹效果", "ms-appx:///Shaders/WaveRippleShader.txt", "波纹效果")]
        WaveRipple,
        [ShaderInfo("波浪效果", "ms-appx:///Shaders/WaveShader.txt", "波浪效果")]
        Wave,
        [ShaderInfo("液化效果", "ms-appx:///Shaders/Liquefaction.txt", "液化效果")]
        Liquefaction,
        [ShaderInfo("液化效果", "ms-appx:///Shaders/LiquefactionAbsoluteSampling.txt", "液化效果绝对采样")]
        LiquefactionAbsoluteSampling,
        [ShaderInfo("液化效果", "ms-appx:///Shaders/LiquefactionMapping.txt", "液化效果映射采样")]
        LiquefactionMapping,
        [ShaderInfo("液化效果", "ms-appx:///Shaders/LiquefactionSampling.txt", "液化效果映射采样")]
        LiquefactionSampling,
        [ShaderInfo("液化效果", "ms-appx:///Shaders/LiqueArea.txt")]
        LiqueArea,
        [ShaderInfo("定向模糊", "ms-appx:///Shaders/DirectionalBlur.txt")]
        DirectionalBlur,
        [ShaderInfo("径向模糊", "ms-appx:///Shaders/RadialBlur.txt")]
        RadialBlur,
        [ShaderInfo("旋转模糊", "ms-appx:///Shaders/RotateBlur.txt")]
        RotateBlur,
        [ShaderInfo("晶格笔刷", "ms-appx:///Shaders/LatticeBrush.txt")]
        LatticeBrush,
        [ShaderInfo("平面到极坐标效果", "ms-appx:///Shaders/CoorPlanePolar.txt")]
        CoorPlanePolar,
        [ShaderInfo("极坐标到平面", "ms-appx:///Shaders/PolarPlaneCoorr.txt")]
        PolarPlaneCoorr,
        [ShaderInfo("扇形效果", "ms-appx:///Shaders/SectorGraphics.txt")]
        SectorGraphics,
        [ShaderInfo("油画效果", "ms-appx:///Shaders/Painting.txt")]
        Painting,
        [ShaderInfo("素描效果", "ms-appx:///Shaders/Pencil.txt")]
        Pencil,
        [ShaderInfo("置换伪3D效果", "ms-appx:///Shaders/Displacement3D.txt")]
        Displacement3D,
        [ShaderInfo("买塞克效果", "ms-appx:///Shaders/Mosaic.bin")]
        Mosaic,
    }

    public static class ShaderExtensions
    {
        //@Static
        public static async Task<byte[]> LoadAsync(this ShaderType type)
        {
            string path = type.GetPath();
            if (string.IsNullOrEmpty(path))
                return null;
            StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(path));
            IBuffer buffer = await FileIO.ReadBufferAsync(file);
            return buffer.ToArray();
        }
        private static string GetPath(this ShaderType type)
        {
            var typeInfo = (TypeInfo)type.GetType();
            FieldInfo fi = typeInfo.GetField(type.ToString());

            var info = fi.GetCustomAttribute<ShaderInfoAttribute>();
            if (info != null)
            {
                return info.Path;
            };
            return null;
        }
    }
}